package com.retailcloud.thirdpartyservice.config;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;

import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Configuration
public class WechatMpConfig {

    @Value("${wechat.appid}")
    private static  String APP_ID = "wxd14a2245cdd1eed8";
    @Value("${wechat.secret}")
    private static  String APP_SECRET = "121d1c56423941f678bc7bffde7d842e";

    @Resource
    private AccessTokenCache accessTokenCache;

    private final Lock lock = new ReentrantLock();

    @Bean
    public WxMaService wxMaService() {
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(wxMaConfig());
        return wxMaService;
    }

    @Bean
    public WxMaConfig wxMaConfig() {
        return new WxMaConfig() {
            @Override
            public String getAccessToken() {
                String accessToken = accessTokenCache.get(APP_ID);
                if (accessToken == null || accessTokenCache.isExpired(APP_ID)) {
                    try {
                        lock.lock();
                        accessToken = accessTokenCache.get(APP_ID);
                        if (accessToken == null || accessTokenCache.isExpired(APP_ID)) {
                            accessToken = refreshAccessToken();
                            accessTokenCache.put(APP_ID, accessToken, 7200); // 默认有效期为 7200 秒
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        lock.unlock();
                    }
                }
                return accessToken;
            }

            @Override
            public Lock getAccessTokenLock() {
                return lock;
            }

            @Override
            public boolean isAccessTokenExpired() {
                return accessTokenCache.isExpired(APP_ID);
            }

            @Override
            public void expireAccessToken() {
                accessTokenCache.put(APP_ID, "", 0);
            }

            @Override
            public void updateAccessToken(WxAccessToken wxAccessToken) {
                accessTokenCache.put(APP_ID, wxAccessToken.getAccessToken(), wxAccessToken.getExpiresIn());
            }

            @Override
            public void updateAccessToken(String accessToken, int expiresInSeconds) {
                accessTokenCache.put(APP_ID, accessToken, expiresInSeconds);
            }

            @Override
            public String getJsapiTicket() {
                return null; // 如果需要手动管理 jsapi ticket 可以重写此方法
            }

            @Override
            public Lock getJsapiTicketLock() {
                return null;
            }

            @Override
            public boolean isJsapiTicketExpired() {
                return false;
            }

            @Override
            public void expireJsapiTicket() {

            }

            @Override
            public void updateJsapiTicket(String ticket, int expiresInSeconds) {

            }

            @Override
            public String getCardApiTicket() {
                return null;
            }

            @Override
            public Lock getCardApiTicketLock() {
                return null;
            }

            @Override
            public boolean isCardApiTicketExpired() {
                return false;
            }

            @Override
            public void expireCardApiTicket() {

            }

            @Override
            public void updateCardApiTicket(String ticket, int expiresInSeconds) {

            }

            @Override
            public String getAppid() {
                return APP_ID;
            }

            @Override
            public String getSecret() {
                return APP_SECRET;
            }

            @Override
            public String getToken() {
                return null; // 微信公众号的 token，小程序不需要
            }

            @Override
            public String getAesKey() {
                return null; // 微信公众号的 aes key，小程序不需要
            }

            @Override
            public String getOriginalId() {
                return null;
            }

            @Override
            public String getCloudEnv() {
                return null;
            }

            @Override
            public String getMsgDataFormat() {
                return null;
            }

            @Override
            public long getExpiresTime() {
                return 0;
            }

            @Override
            public String getHttpProxyHost() {
                return null;
            }

            @Override
            public int getHttpProxyPort() {
                return 0;
            }

            @Override
            public String getHttpProxyUsername() {
                return null;
            }

            @Override
            public String getHttpProxyPassword() {
                return null;
            }

            @Override
            public int getRetrySleepMillis() {
                return 0;
            }

            @Override
            public int getMaxRetryTimes() {
                return 0;
            }

            @Override
            public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
                return null;
            }

            @Override
            public boolean autoRefreshToken() {
                return false;
            }

            @Override
            public void setApiHostUrl(String url) {

            }

            @Override
            public String getApiHostUrl() {
                return null;
            }

            @Override
            public String getAccessTokenUrl() {
                return null;
            }

            @Override
            public void setAccessTokenUrl(String url) {

            }

            private String refreshAccessToken() throws Exception {
                String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Accept", "application/json");

                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();

                    // 解析 JSON 响应
                    int startIndex = response.indexOf("\"access_token\":\"") + 15;
                    int endIndex = response.indexOf("\"", startIndex);
                    String accessToken = response.substring(startIndex, endIndex);
                    return accessToken;
                } else {
                    throw new RuntimeException("Failed to refresh access token: " + responseCode);
                }
            }
        };
    }
}
